package com.turing.post.cardmanagement.impl;

import java.math.BigInteger;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.turing.post.cardmanagement.util.CardManaApplicationException;
import com.turing.post.cardmanagement.util.CardManaRespCode;
import com.turing.post.cardmanagement.util.CardStock;
import com.turing.post.cardmanagement.util.CardStockBusiness;
import com.turing.post.cardmanagement.util.CardStockDao;
import com.turing.post.cardmanagement.util.InitialInStockOrder;
import com.turing.post.cardmanagement.util.InitialInStockOrderDao;
import com.turing.post.cardmanagement.util.IssueCardStockDetail;
import com.turing.post.cardmanagement.util.IssueCardStockDetailDao;
import com.turing.post.cardmanagement.util.MakeCardControl;
import com.turing.post.cardmanagement.util.MakeCardControlBusiness;
import com.turing.post.cardmanagement.util.MakeCardControlDao;
import com.turing.post.cardmanagement.util.NonEntityCard;
import com.turing.post.cardmanagement.util.NonEntityCardDao;
import com.turing.post.common.util.PCPSCommonDao;
import com.turing.post.common.util.SysOpUserDao;
import com.turing.post.common.util.SysOperLog;
import com.turing.post.common.util.SysOperLogDao;
import com.turing.post.organization.util.IssueCompany;
import com.turing.post.organization.util.IssueCompanyDao;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;
import com.turing.post.util.PCPSWebInput;

/**
 * 卡片库存业务实现
 * 
 * @author YangShuo
 * 
 */

@Stateless(mappedName = "cardmanagement.impl.CardStockBusinessImpl")
@Remote
@Local
public class CardStockBusinessImpl implements CardStockBusiness {

	@PersistenceContext
	protected EntityManager _em;

	@EJB(mappedName = "common.impl.PCPSCommonDaoImpl")
	private PCPSCommonDao pcpsCommonDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.NonEntityCardDaoImpl")
	private NonEntityCardDao NonEntityCardDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.MakeCardControlDaoImpl")
	private MakeCardControlDao MakeCardControlDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.CardStockDaoImpl")
	private CardStockDao CardStockDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.InitialInStockOrderDaoImpl")
	private InitialInStockOrderDao InitialInStockOrderDaoImpl;

	@EJB(mappedName = "common.impl.SysOperLogDaoImpl")
	private SysOperLogDao sysOperLogDaoImpl;
	@EJB(mappedName = "cardmanagement.impl.MakeCardControlBusinessImpl")
	private MakeCardControlBusiness MakeCardControlBusinessImpl;

	@EJB(mappedName = "common.impl.SysOpUserDaoImpl")
	private SysOpUserDao SysOpUserDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.IssueCardStockDetailDaoImpl")
	private IssueCardStockDetailDao IssueCardStockDetailDaoImpl;

	@EJB(mappedName = "organization.impl.IssueCompanyDaoImpl")
	private IssueCompanyDao IssueCompanyDaoImpl;

	/**
	 * 异常抛出方法
	 * 
	 * @param error
	 * @throws PCPSApplicationException
	 */
	private void errException(String error) throws PCPSApplicationException {
		throw new CardManaApplicationException(
				CardManaApplicationException.ERRCODE_CATEGORY_APPLICATION,
				CardManaRespCode.RC_ARGS_NULL, error);
	}

	/**
	 * 卡片入库撤销
	 * 
	 * @param BatchNo
	 * @param startCardSeqno
	 * @param endCardSeqnoString
	 * 
	 */
	@Override
	public void putInCancleCardStock(PCPSWebInput input,
			InitialInStockOrder _iiso, BigInteger operno)
			throws PCPSApplicationException {
		// 根据InitialInStockOrderId取得需要取消的入库信息
		InitialInStockOrder iiso = InitialInStockOrderDaoImpl
				.getInitialInStockOrderByCardInitialInStockOrderId(_iiso
						.getInitialInStockOrderId());
		if (iiso == null) {
			errException("入库单编号输入错误,未查询到入库信息!");
		}
		if (!iiso.getStatus().equals(
				InitialInStockOrder.InStockOrder_Status_Input)) {
			errException("只可对已审核的入库单进行撤销!");
		}
		if(_iiso.getOperId().compareTo(input.getOperId())!=0){
			errException("申请人和入库人不是同一个人!");
		}
		// 根据Batchno取得制卡信息
		// MakeCardControl mcc = MakeCardControlDaoImpl
		// .getMakeCardControlByBatchNo(iiso.getBatchNo());
		// 从CardStock中查询出需要取消的卡信息集合
		List<CardStock> cardstocklist = CardStockDaoImpl
				.getCardStockListCountBySysbranchnoNoAndStatusAndCredseqno(iiso
						.getCardStartSeqNo(), iiso.getCardEndSeqNo(),
						CardStock.CARDSTOCK_STATUS_NORMAL, iiso
								.getIssueBranchNo());
		// 如果状态是正常的卡库存数量不符，报错
		if (cardstocklist.size() != iiso.getInStockCount())
			errException("库存中对应卡数量不符，该批入库卡片已有部分卡被调整、销售或调拨，无法撤销入库!");

		// IssueCompany ic = IssueCompanyDaoImpl
		// .getIssueCompanyByIssueCompanyNo(iiso.getBatchNo().substring(0,
		// 6));
		// 给出入库明细记录一条记录
		// IssueCardStockDetail ics = new IssueCardStockDetail();
		// ics.setIoOrderId(iiso.getInitialInStockOrderId());
		// ics.setIssueBranchNo(iiso.getIssueBranchNo());
		// ics.setTranDate(ic.getTranDate());
		// ics.setTrantime(pcpsCommonDaoImpl.getDatabaseSysTime());
		// ics.setTranType(IssueCardStockDetail.ISSUECARDSTOCKDETAIL_TRANTYPE_WaitMAKECancel);
		// ics.setCardFaceId(mcc.getCardFaceId());
		// ics.setBatchNo(mcc.getBatchNo());
		// ics.setCardStartSeqNo(iiso.getCardStartSeqNo());
		// ics.setCardEndSeqNo(iiso.getCardEndSeqNo());
		// ics.setOrderCount(iiso.getInStockCount() * -1);// 取消操作记录负数
		// ics.setOperId(input.getOperId());
		// ics.setRemark(_iiso.getRemark());
		// IssueCardStockDetailDaoImpl.insert(ics);
		// 更新状态
		iiso.setStatus(InitialInStockOrder.InStockOrder_Status_OutWait);
		iiso.setCancelInStockTime(pcpsCommonDaoImpl.getDatabaseSysTime());
		InitialInStockOrderDaoImpl.updateInitialInStockOrderForCancel(iiso);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(input, SysOperLog.operType_Edit,
				"卡片入库撤销", "InitialInStockOrderId:"
						+ iiso.getInitialInStockOrderId());
	}

	// 卡片入库撤销审核
	@Override
	public void putInCancleCardStockAuth(PCPSWebInput input,
			InitialInStockOrder _iiso, BigInteger operno)
			throws PCPSApplicationException {
		// 根据InitialInStockOrderId取得需要取消的入库信息
		InitialInStockOrder iiso = InitialInStockOrderDaoImpl
				.getInitialInStockOrderByCardInitialInStockOrderId(_iiso
						.getInitialInStockOrderId());
		if (iiso == null) {
			errException("入库单编号输入错误,未查询到入库信息!");
		}
		if (!iiso.getStatus().equals(
				InitialInStockOrder.InStockOrder_Status_OutWait)) {
			errException("该撤销入库单不为撤销待审状态!");
		}
		if(_iiso.getOperId().compareTo(input.getOperId())==0){
			errException("审核人和申请人不能是同一个人!");
		}
		// 根据Batchno取得制卡信息
		MakeCardControl mcc = MakeCardControlDaoImpl
				.getMakeCardControlByBatchNo(iiso.getBatchNo());

		// 从CardStock中查询出需要取消的卡信息集合
		List<CardStock> cardstocklist = CardStockDaoImpl
				.getCardStockListCountBySysbranchnoNoAndStatusAndCredseqno(iiso
						.getCardStartSeqNo(), iiso.getCardEndSeqNo(),
						CardStock.CARDSTOCK_STATUS_NORMAL, iiso
								.getIssueBranchNo());
		// 如果状态是正常的卡库存数量不符，报错
		if (cardstocklist.size() != iiso.getInStockCount())
			errException("库存中对应卡数量不符，该批入库卡片已有部分卡被调整、销售或调拨，无法取消入库!");
		// 将待制回卡插入待制卡列表
		CardStock cs = null;
		for (int i = 0; i < cardstocklist.size(); i++) {
			cs = cardstocklist.get(i);
			NonEntityCard nec = new NonEntityCard();
			nec.setBatchNo(cs.getBatchNo());
			nec.setCardNo(cs.getCardNo());
			nec.setCardPwd(cs.getCardPwd());
			nec.setCardSeqNo(cs.getCardSeqNo());
			nec.setTwoTrackContent(cs.getTwoTrackContent());
			nec.setThirdTrackContent(cs.getThirdTrackContent());
			NonEntityCardDaoImpl.insertNonEntityCard(nec);
		}

		// 将CardStock表中数据删除
		CardStockDaoImpl.deleteCardStock(iiso.getBatchNo(), iiso
				.getCardStartSeqNo(), iiso.getCardEndSeqNo());

		MakeCardControlBusinessImpl.checkAlreadyInStockCount(iiso
				.getInStockCount()
				* -1, iiso.getBatchNo());
		IssueCompany ic = IssueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(PCPSUtil
						.getICNoByBranchNo(iiso.getIssueBranchNo()));
		// 给出入库明细记录一条记录
		IssueCardStockDetail ics = new IssueCardStockDetail();
		ics.setIoOrderId(iiso.getInitialInStockOrderId());
		ics.setIssueBranchNo(iiso.getIssueBranchNo());
		ics.setTranDate(ic.getTranDate());
		ics.setTrantime(pcpsCommonDaoImpl.getDatabaseSysTime());
		ics
				.setTranType(IssueCardStockDetail.ISSUECARDSTOCKDETAIL_TRANTYPE_MAKECancel);
		ics.setCardFaceId(mcc.getCardFaceId());

		ics.setBatchNo(mcc.getBatchNo());
		ics.setCardStartSeqNo(iiso.getCardStartSeqNo());
		ics.setCardEndSeqNo(iiso.getCardEndSeqNo());
		ics.setOrderCount(iiso.getInStockCount() * -1);// 取消操作记录负数
		ics.setOperId(iiso.getOperId());
		ics.setRemark(_iiso.getRemark());
		IssueCardStockDetailDaoImpl.insert(ics);
		// 在InitialInStockOrder中修改状态
		iiso.setStatus(InitialInStockOrder.InStockOrder_Status_Out);
		iiso.setAuthOperId(input.getOperId());
		iiso.setAuthTime(pcpsCommonDaoImpl.getDatabaseSysTime());
		InitialInStockOrderDaoImpl.updateInitialInStockOrderForCancel(iiso);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(input, SysOperLog.operType_Edit,
				"卡片入库撤销审核", "InitialInStockOrderId:"
						+ iiso.getInitialInStockOrderId());
	}

	/**
	 * 实物卡入库-待审
	 * 
	 * @param BatchNo
	 * @param startCardSeqno
	 * @param endCardSeqnoString
	 * 
	 */
	@Override
	public BigInteger putInCardStock(PCPSWebInput input,
			InitialInStockOrder iiso) throws PCPSApplicationException {
		if (iiso.getOperId() == null) {
			errException("操作员号为空!");
		}
		// 检查非空项
		if (PCPSUtil.isEmpty(iiso.getBatchNo()))
			errException("批次号为空!");
		if (PCPSUtil.isEmpty(iiso.getCardStartSeqNo()))
			errException("起始序号为空!");
		if (PCPSUtil.isEmpty(iiso.getCardEndSeqNo()))
			errException("结束序号为空!");
		// 根据Batchno取得制卡信息
		MakeCardControl mcc = MakeCardControlDaoImpl
				.getMakeCardControlByBatchNo(iiso.getBatchNo());
		// 判断操作员是否是该机构的，不允许操作其他机构的库存
		String operbranchno = SysOpUserDaoImpl.getSysOpUserByOperId(
				iiso.getOperId()).getOperBranchNo();
		if (!mcc.getIssueBranchNo().equals(operbranchno))
			errException("操作员不属于此机构!");
		// 判断该入库单申请已经存在
		List<InitialInStockOrder> existList = InitialInStockOrderDaoImpl
				.getInitialInStockOrderListByCond(iiso,
						InitialInStockOrder.InStockOrder_Status_InputWait);
		if (existList != null && existList.size() > 0) {
			errException("已存在" + existList.get(0).getCardStartSeqNo() + "到"
					+ existList.get(0).getCardEndSeqNo() + "申请入库记录!");
		}
		// PCPSUtil.Log("Start Serch NonEntityCardlist");
		// long start = System.currentTimeMillis();
		// 根据BatchNo，起止序号，得到卡集合
		// List<NonEntityCard> NonEntityCardlist = NonEntityCardDaoImpl
		// .getNonEntityCardListByBatchnoAndSeqno(iiso.getBatchNo(), iiso
		// .getCardStartSeqNo(), iiso.getCardEndSeqNo());
		Integer nonEntityCardCount = NonEntityCardDaoImpl
				.getNonEntityCardCountByBatchnoAndSeqno(iiso.getBatchNo(), iiso
						.getCardStartSeqNo(), iiso.getCardEndSeqNo());
		// PCPSUtil.Log("End Serch NonEntityCardlist"
		// + (System.currentTimeMillis() - start));
		// 检验卡号是否连续，未入库库存是否正确
		// InStockCount制卡张数。
		int InStockCount = 0;
		if (iiso.getCardEndSeqNo().trim().length() < 18) {
			InStockCount = ((Integer.parseInt(iiso.getCardEndSeqNo().substring(
					6, 12))
					- Integer.parseInt(iiso.getCardStartSeqNo()
							.substring(6, 12)) + 1));
		} else {
			InStockCount = ((Integer.parseInt(iiso.getCardEndSeqNo().substring(
					12, 18))
					- Integer.parseInt(iiso.getCardStartSeqNo().substring(12,
							18)) + 1));
		}
		if (InStockCount != nonEntityCardCount)
			errException("输入的序列号段有误或者批次号有误,入库张数和实际未入库张数不符!");

		// 生成入库单信息插入
		iiso
				.setInitialInStockOrderId((pcpsCommonDaoImpl
						.getUniqueIntegerKey()));
		iiso.setInStockCount(InStockCount);
		IssueCompany ic = IssueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(mcc.getIssueCompanyNo());
		iiso.setOrderNumber(pcpsCommonDaoImpl.getOrderNumber(ic.getTranDate(),
				operbranchno));// 单号
		iiso.setIssueBranchNo(mcc.getIssueBranchNo());
		iiso.setInStockTime(pcpsCommonDaoImpl.getDatabaseSysTime());
		iiso.setStartCardNo(NonEntityCardDaoImpl.getNonEntityCardBycardseqno(
				iiso.getCardStartSeqNo()).getCardNo());
		iiso.setEndCardNo(NonEntityCardDaoImpl.getNonEntityCardBycardseqno(
				iiso.getCardEndSeqNo()).getCardNo());
		iiso.setStatus(InitialInStockOrder.InStockOrder_Status_InputWait);// 入库待审
		InitialInStockOrderDaoImpl.insertInitialInStockOrder(iiso);
		// 给出入库明细记录一条记录 申请不添加明细
		// IssueCardStockDetail ics = new IssueCardStockDetail();
		// ics.setIoOrderId(iiso.getInitialInStockOrderId());
		// ics.setIssueBranchNo(iiso.getIssueBranchNo());
		// ics.setTranDate(ic.getTranDate());
		// ics.setTrantime(pcpsCommonDaoImpl.getDatabaseSysTime());
		// ics.setTranType(IssueCardStockDetail.ISSUECARDSTOCKDETAIL_TRANTYPE_MAKE);
		// ics.setCardFaceId(mcc.getCardFaceId());
		// ics.setBatchNo(mcc.getBatchNo());
		// ics.setCardStartSeqNo(iiso.getCardStartSeqNo());
		// ics.setCardEndSeqNo(iiso.getCardEndSeqNo());
		// ics.setOrderCount(iiso.getInStockCount());
		// ics.setOperId(iiso.getOperId());
		// ics.setRemark(iiso.getRemark());
		// IssueCardStockDetailDaoImpl.insert(ics);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(input, SysOperLog.operType_Edit,
				"卡片入库待审", "InitialInStockOrderId:"
						+ iiso.getInitialInStockOrderId());
		return iiso.getInitialInStockOrderId();
	}

	// 入库审核
	@Override
	public void putInCardStockAuth(PCPSWebInput input, InitialInStockOrder _iiso)
			throws PCPSApplicationException {
		if (_iiso.getInitialInStockOrderId() == null) {
			errException("制卡入库单编号为空!");
		}
		// 制卡入库单
		InitialInStockOrder iiso = InitialInStockOrderDaoImpl
				.getInitialInStockOrderByCardInitialInStockOrderId(_iiso
						.getInitialInStockOrderId());
		if (iiso == null) {
			errException("传入的制卡入库单编号有误!");
		}
		if (!iiso.getStatus().equals(
				InitialInStockOrder.InStockOrder_Status_InputWait)) {
			errException("该入库单状态不为入库待审状态!");
		}
		if(_iiso.getOperId().compareTo(input.getOperId())==0){
			errException("审核人和申请人不能是同一个人!");
		}
		MakeCardControl mcc = MakeCardControlDaoImpl
				.getMakeCardControlByBatchNo(iiso.getBatchNo());
		// 根据BatchNo，起止序号，得到卡集合
		List<NonEntityCard> NonEntityCardlist = NonEntityCardDaoImpl
				.getNonEntityCardListByBatchnoAndSeqno(iiso.getBatchNo(), iiso
						.getCardStartSeqNo(), iiso.getCardEndSeqNo());
		// InStockCount制卡张数。
		int InStockCount = 0;
		if (iiso.getCardEndSeqNo().trim().length() < 18) {
			InStockCount = ((Integer.parseInt(iiso.getCardEndSeqNo().substring(
					6, 12))
					- Integer.parseInt(iiso.getCardStartSeqNo()
							.substring(6, 12)) + 1));
		} else {
			InStockCount = ((Integer.parseInt(iiso.getCardEndSeqNo().substring(
					12, 18))
					- Integer.parseInt(iiso.getCardStartSeqNo().substring(12,
							18)) + 1));
		}
		if (InStockCount != NonEntityCardlist.size())
			errException("入库单中卡顺序号不连续!");
		String batchNo = iiso.getBatchNo();// 批次号
		// 将信息写入CardStock表
		NonEntityCard nec = null;
		CardStock cs = null;
		int size = NonEntityCardlist.size();
		for (int i = 0; i < size; i++) {
			nec = NonEntityCardlist.get(i);
			cs = new CardStock();
			cs.setBatchNo(nec.getBatchNo());
			cs.setCardNo(nec.getCardNo());
			cs.setCardPwd(nec.getCardPwd());
			cs.setCardSeqNo(nec.getCardSeqNo());
			cs.setIssueBranchNo(mcc.getIssueBranchNo());
			cs.setStatus(CardStock.CARDSTOCK_STATUS_NORMAL);
			cs.setTwoTrackContent(nec.getTwoTrackContent());
			cs.setThirdTrackContent(nec.getThirdTrackContent());
			CardStockDaoImpl.insertCardStock(cs);
		}
		// 将NonEntityCard里的数据删除
		NonEntityCardDaoImpl
				.deleteNonEntityCardListByBatchnoAndSeqno(iiso.getBatchNo(),
						iiso.getCardStartSeqNo(), iiso.getCardEndSeqNo());
		// 修改制卡控制表的状态
		MakeCardControlBusinessImpl.checkAlreadyInStockCount(InStockCount,
				batchNo);
		IssueCompany ic = IssueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(PCPSUtil
						.getICNoByBranchNo(iiso.getIssueBranchNo()));

		IssueCardStockDetail ics = new IssueCardStockDetail();
		ics.setIoOrderId(iiso.getInitialInStockOrderId());
		ics.setIssueBranchNo(iiso.getIssueBranchNo());
		ics.setTranDate(ic.getTranDate());
		ics.setTrantime(pcpsCommonDaoImpl.getDatabaseSysTime());
		ics
				.setTranType(IssueCardStockDetail.ISSUECARDSTOCKDETAIL_TRANTYPE_WAITMAKE);
		ics.setCardFaceId(mcc.getCardFaceId());
		ics.setBatchNo(mcc.getBatchNo());
		ics.setCardStartSeqNo(iiso.getCardStartSeqNo());
		ics.setCardEndSeqNo(iiso.getCardEndSeqNo());
		ics.setOrderCount(iiso.getInStockCount());
		ics.setOperId(iiso.getOperId());
		ics.setRemark(iiso.getRemark());

		IssueCardStockDetailDaoImpl.insert(ics);
		// 修改入库单状态
		iiso.setAuthOperId(input.getOperId());
		iiso.setAuthTime(pcpsCommonDaoImpl.getDatabaseSysTime());
		iiso.setStatus(InitialInStockOrder.InStockOrder_Status_Input);// 状态改为入库
		InitialInStockOrderDaoImpl.updateInitialInStockOrderForCancel(iiso);
		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(input, SysOperLog.operType_Edit,
				"卡片入库审核", "InitialInStockOrderId:"
						+ iiso.getInitialInStockOrderId());
	}
}
